<?php
	abstract class Controller
	{
		var $ControllerName;
		var $ActionName;
		var $PageParameters;
		var $RequestData;
		var $ViewData;
		var $PageTitle;
		
		function __construct()
		{
			$RequestData = $this->_LoadRequestVariables();
		}
		
		function InvokeAction()
		{
			$actionFunctionName = $this->QualifyObjectName($this->ActionName);
			if ( method_exists($this, $actionFunctionName) )
			{
 	   			$this->$actionFunctionName();
			}
			elseif ( $this->_htmlViewExists($this->ControllerName, $this->ActionName) )
			{
				$this->View();
			}
			else
			{
				Do404();
			}
			
		}
		
		private function _LoadRequestVariables()
		{
			$values = array();
			
	        foreach ($_REQUEST as $key => $value)
	        {
	            $values[$key] = $_REQUEST[$key];
	        }
	        
	        return $values;
		}
			
		function LoadRepository($modelName)
		{
			
			$path = REPOSITORY_PATH.'/'.strtolower($modelName).'.php';
			
			if ( file_exists($path) )
			{
				include_once($path);
				
				$repositoryClassName = $this->QualifyObjectName($modelName).'Repository';
	    		
	    		if (class_exists($repositoryClassName) && get_parent_class($repositoryClassName) == 'Repository')
	    		{
	    			
	    			$repository = new $repositoryClassName();
	    			return $repository;
	    		}
			}
			
			return null;
		}
				
		static function NormalizeObjectName($name)
		{
			return strtolower(preg_replace('/-/', '_', $name));
		}
		
		static function QualifyObjectName($name)
		{
			$parts = explode('_', $name);
			
			foreach($parts as &$i)
			{
				$i = ucfirst($i);
			}
			
			return $name = implode('', $parts);
		}
		
		function View()
		{
			$this->ViewNamed($this->ActionName, $this->viewData);
		}
		
		function ViewNamed($viewName)
		{
			$this->_htmlView($viewName, $this->viewData);
		}
		
		function ViewWithData($data)
		{
			$this->_htmlView($this->ActionName, $data);
		}
		
		function ViewNamedWithData($viewName, $data)
		{
			$this->_htmlView($viewName, $data);
		}
		
		private function _htmlView($viewName, $viewData)
		{
			$skinPath = 'application/views/skins/html.php';
			$viewPath = 'application/views/'.$this->ControllerName.'/'.$viewName.'.php';
			
			$Model = $this->ViewData;
			$PageTitle = $this->PageTitle;

			$Helper = new ViewHelper($this->ControllerName, $this->ActionName, $Model);
						
			ob_start();
		    include_once($viewPath);
			$viewHtml = ob_get_contents();
    		ob_end_clean();
    		
			include_once($skinPath);
		}
		
		private function _htmlViewExists($controllerName, $actionName)
		{
			$viewPath = 'application/views/'.$controllerName.'/'.$actionName.'.php';
			return file_exists($viewPath);
		}
		
		function Json()
		{
			$this->_jsonView($this->ViewData);
		}
		
		function JsonWithData($data)
		{
			$this->_jsonView($data);
		}
		
		function _jsonView($viewData)
		{
			$json = json_encode($viewData);
			
        	header('Content-Type: application/json');
        	print($json);
        	
        	exit();
		}
		
		function RequireHttpGet() {
	        if (strtoupper($_SERVER['REQUEST_METHOD']) != 'GET') {
	            $this->PageNotFound();
	        }
	    }
	
	    function RequireHttpPost() {
	        if (strtoupper($_SERVER['REQUEST_METHOD']) != 'POST') {
	            $this->PageNotFound();
	        }
	    }
	    function RedirectToAction($c, $a) {
	    	
	    	$url = BASE_URL.urlencode($c).'/'.urlencode($a);
	    	
	    	if ( strtolower($a) == 'index' )
	    	{
	    		$url = BASE_URL.urlencode($c).'/';
	    		
	    		if ( strtolower($c) == 'home' )
	    		{
	    			$url = BASE_URL;
	    		}
	    	}
	    	
	        header("Location: $url");
	        exit();
	    }
	    
	    function RedirectToController($c)
	    {
	    	RedirectToAction($c, '');
	    }
	    
		function PageNotFound()
		{
			$this->RedirectToAction('Errors','Page-Not-Found');
		}
	}
?>